﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;
using Core;
using Core.UIItems;
using Core.UIItems.ListBoxItems;
using Core.UIItems.WindowItems;
using Core.InputDevices;
using System.Xml;


namespace UITestSuite
{
    public class UITestHelperClass
    {
        /// <summary>
        /// Remove any standard and custom Offline Store DB
        /// </summary>
        /// <param name="testStandardDataStoreFileName"></param>
        /// <param name="testCustomDataStoreFileName"></param>
        public static void DeleteOfflineStore(string testStandardDataStoreFileName, string testCustomDataStoreFileName)
        {
            try
            {
                if (!String.IsNullOrEmpty(testStandardDataStoreFileName))
                {
                    Directory.Delete(testStandardDataStoreFileName, true);
                }
                if (!String.IsNullOrEmpty(testCustomDataStoreFileName))
                {
                    File.Delete(testCustomDataStoreFileName);
                }
            }
            catch { }
        }

        /// <summary>
        /// Deletes user.config files under ForumsClient directories
        /// by deleting the directories
        /// </summary>
        public static void DeleteUserConfigFile()
        {
            try
            {
                string path = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Microsoft";
                string[] forumsClientDirectories = Directory.GetDirectories(path);
                foreach (string directoryName in forumsClientDirectories)
                {
                    if (directoryName.Contains("ForumsClient"))
                    {
                        Directory.Delete(directoryName, true);
                    }
                }
            }
            catch { }
        }

        /// <summary>
        /// Find the Live ID Login window and sign in using the data supplied by caller
        /// </summary>
        /// <param name="logonInformation"></param>
        public static void Logon(Window mainWindow, LogonInformation logonInformation)
        {
            Window loginDialogWindow;

            loginDialogWindow = mainWindow.ModalWindow("LiveID Login", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(loginDialogWindow);

            ComboBox userLogonNameComboBox = loginDialogWindow.Get<ComboBox>("EmailCmbBox");
            Assert.IsNotNull(userLogonNameComboBox);

            TextBox passwordTextBox = loginDialogWindow.Get<TextBox>("PwdTxtBox");
            Assert.IsNotNull(passwordTextBox);

            CheckBox rememberMeCheckBox = loginDialogWindow.Get<CheckBox>("RemNameChk");
            Assert.IsNotNull(rememberMeCheckBox);

            CheckBox rememberMyPasswordCheckBox = loginDialogWindow.Get<CheckBox>("RemPwdChk");
            Assert.IsNotNull(rememberMyPasswordCheckBox);

            userLogonNameComboBox.Enter(logonInformation.UserID);

            // If rememberMe is true and the check box isn't checked or 
            // if rememberMe is false and checkbox is checked, click the 
            // checkbox to change its state
            if (logonInformation.RememberUser != rememberMeCheckBox.Checked)
            {
                rememberMeCheckBox.Click();
            }

            // If the password wasn't saved last time for this user, we have to enter it
            if (rememberMyPasswordCheckBox.Checked == false)
            {
                passwordTextBox.Text = logonInformation.UserPassword;
            }

            // If the remember my password checkbox doesn't match what the user wants, click it to change the state
            if (logonInformation.RememberUserPassword != rememberMyPasswordCheckBox.Checked)
            {
                rememberMyPasswordCheckBox.Click();
                // If it was true and we changed it to false, we have to enter password
                if (rememberMyPasswordCheckBox.Checked == false)
                {
                    passwordTextBox.Text = logonInformation.UserPassword;
                }
            }

            Button signInButton = loginDialogWindow.Get<Button>("SignInBtn");
            Assert.IsNotNull(signInButton);
            signInButton.Click();
            System.Threading.Thread.Sleep(logonInformation.PostLogonSleepInterval);
        }

        /// <summary>
        /// Clicks the LiveID Login's cancel button using Automation ID
        /// </summary>
        /// <param name="mainWindow"></param>
        public static void CancelLogon(Window mainWindow)
        {
            Window loginDialogWindow;

            loginDialogWindow = mainWindow.ModalWindow("LiveID Login", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(loginDialogWindow);

            Button closeButton = loginDialogWindow.Get<Button>("CloseBtn");
            Assert.IsNotNull(closeButton);
            closeButton.DoubleClick();
        }
    }

    /// <summary>
    /// Information to use for test's logon
    /// </summary>
    public class LogonInformation
    {
        private string userID;
        private string userPassword;
        private bool rememberUser;
        private bool rememberUserPassword;
        private int postLogonSleepInterval;

        /// <summary>
        /// User's Live ID logon name
        /// </summary>
        public string UserID
        {
            get { return userID; }
            set { userID = value; }
        }

        /// <summary>
        /// User's Live ID password
        /// </summary>
        public string UserPassword
        {
            get { return userPassword; }
            set { userPassword = value; }
        }

        /// <summary>
        /// Should the test check the Live ID Remember Me box?
        /// </summary>
        public bool RememberUser
        {
            get { return rememberUser; }
            set { rememberUser = value; }
        }

        /// <summary>
        /// Should the test check the Live ID Remember Password box
        /// </summary>
        public bool RememberUserPassword
        {
            get { return rememberUserPassword; }
            set { rememberUserPassword = value; }
        }

        public int PostLogonSleepInterval
        {
            get { return postLogonSleepInterval; }
            set { postLogonSleepInterval = value; }
        }
    }

    /// <summary>
    /// Class provides test parameters from an XML file
    /// </summary>
    public class TestParameters
    {     
        private XmlDocument parameterFile;
        private string UITestsParametergFile = "UITestParameters.xml";
        private XmlElement parameterRoot;
        private XmlNode parameterNode;
        private LogonInformation logonInfo;
        private string customDataStoreFileName;
        private string standardDataStoreFolderName;

        // We need to wait for the new forums to arrive over the internet 
        // after changing brands or locales in the subscription dialog tests
        private int postBrandOrLocaleChangeSleepInterval = 2000;


        /// <summary>
        /// Constructor loads XML document and calls methods to parse parameters
        /// </summary>
        public TestParameters()
        {
            string parameterFileFullName = Environment.CurrentDirectory + "\\" + UITestsParametergFile;
            parameterFile = new XmlDocument();
            parameterFile.Load(parameterFileFullName);
            parameterRoot = parameterFile.DocumentElement;

            LoadDataStoreFileNames();            

            logonInfo = new LogonInformation();
            LoadLogonInformation();
            LoadSleepInterval();
        }

        /// <summary>
        /// returns the logon parameters defined by XML file
        /// </summary>
        public LogonInformation LogonInfo { get { return logonInfo; } }

        /// <summary>
        /// return the name of the standard offline data store - used for most tests
        /// </summary>
        public string StandardDataStoreFolderName { get { return standardDataStoreFolderName; } }

        /// <summary>
        /// return the name of the custom offline data store -
        /// used for tests which require customized file name or location
        /// </summary>
        public string CustomDataStoreFileName { get { return customDataStoreFileName; } }

        /// <summary>
        /// get number of milliseconds the user wants to sleep after brand or locale changes
        /// </summary>
        public int PostBrandOrLocaleChangeSleepInterval { get { return postBrandOrLocaleChangeSleepInterval; } }

        private void LoadDataStoreFileNames()
        {
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//StandardTestDBFolderName");
            standardDataStoreFolderName = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\" + parameterNode.InnerText;

            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//CustomTestDBName");
            customDataStoreFileName = parameterNode.InnerText;
        }

        /// <summary>
        /// Parse the XML for PostBrandOrLocaleChangeSleepInterval
        /// </summary>
        private void LoadSleepInterval()
        {
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//PostBrandOrLocaleChangeSleepInterval");

            try
            {
                postBrandOrLocaleChangeSleepInterval = Int32.Parse(parameterNode.InnerText);
            }
            catch
            {
                Console.WriteLine("PostBrandOrLocaleChangeSleepInterval contains invalid integer data - '" + parameterNode.InnerText +
                    "'; Using default of 30 seconds instead.");
                postBrandOrLocaleChangeSleepInterval = 30000;
            }
        }

        /// <summary>
        /// Parse the XML logon parameters and populate the this.logonInfo object
        /// </summary>
        private void LoadLogonInformation()
        {
            bool intermediateValue = false;

            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//LogonInfo//TestUserID");
            logonInfo.UserID = parameterNode.InnerText;
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//LogonInfo//TestUserPassword");
            logonInfo.UserPassword = parameterNode.InnerText;
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//LogonInfo//TestRememberMe");
            Boolean.TryParse(parameterNode.InnerText, out intermediateValue);

            logonInfo.RememberUser = intermediateValue;
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//LogonInfo//TestRememberPassword");
            Boolean.TryParse(parameterNode.InnerText, out intermediateValue);
            logonInfo.RememberUserPassword = intermediateValue;
            parameterNode = parameterRoot.SelectSingleNode("//TestParameters//LogonInfo//PostLogonSleepInterval");

            try
            {
                logonInfo.PostLogonSleepInterval = Int32.Parse(parameterNode.InnerText);
            }
            catch
            {
                Console.WriteLine("PostLogonSleepInterval contains invalid integer data - '" + parameterNode.InnerText +
                    "'; Using default of 30 seconds instead.");
                logonInfo.PostLogonSleepInterval = 30000;
            }

        }
    }
}
